package com.wolfword.crawler.server.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.List;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.github.pagehelper.PageInfo;
import com.wolfword.common.domain.Constant;
import com.wolfword.common.domain.Result;
import com.wolfword.common.domain.ResultConstant;
import com.wolfword.common.domain.ResultMessage;
import com.wolfword.common.util.object.StringUtil;
import com.wolfword.crawler.server.config.Config;
import com.wolfword.crawler.server.entity.CrawlTaskEntity;
import com.wolfword.crawler.server.service.CrawlTaskService;

/**
 * 任务
 * @author Server Zhang
 * @date 2018-01-11 10:54:52
 */
@RestController
@RequestMapping("/task")
@Api(value = "/task", description = "爬取网站任务表相关")
public class CrawlTaskController {
	
	private final Logger logger = LoggerFactory.getLogger(CrawlTaskController.class);
	
	@Value("${html.temp.path}")
	private String htmlTempPath;
	
	@Autowired
	private Config config;
	
    @Autowired
    private CrawlTaskService crawlTaskService;
    
    /**
	 * 任务列表
     * @param request
     * @param url
     * @param parentUrl
     * @param containStr
     * @param status
     * @param pageIndex
     * @param pageSize
     * @return
     * @author ServerZhang
     * @date 2018年1月17日
     */
    @ApiOperation("任务列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "url", value = "地址中包含的串", paramType = "query", dataType = "string", required = false),
            @ApiImplicitParam(name = "parentUrl", value = "父地址中包含的串", paramType = "query", dataType = "string", required = false),
            @ApiImplicitParam(name = "containStr", value = "爬取要求包含的串", paramType = "query", dataType = "string", required = false),
            @ApiImplicitParam(name = "rootUrlId", value = "根网站ID", paramType = "query", dataType = "Integer", required = false),
            @ApiImplicitParam(name = "status", value = "爬取状态：0待爬取，1爬取中，2已完成", paramType = "query", dataType = "Integer", required = false),
            @ApiImplicitParam(name = "sortType", value = "排序：0默认，1邮箱，2电话，3职称，4子页面邮箱，5子页面电话，6子页面职称", paramType = "query", dataType = "Integer", required = false),
            @ApiImplicitParam(name = "pageIndex", value = "页码", paramType = "query", dataType = "Integer", required = false),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", paramType = "query", dataType = "Integer", required = false)
    })
	@PostMapping(value="/list")
	public Result list(HttpServletRequest request,
			String url, String parentUrl, String containStr,
			Long rootUrlId, 
			@RequestParam(value="status",defaultValue="-1")Integer status,
			@RequestParam(value="sortType",defaultValue="0")Integer sortType,
			@RequestParam(value="pageIndex",defaultValue="0")Integer pageIndex,
			@RequestParam(value="pageSize",defaultValue="50") Integer pageSize){
    	
    	if (status.equals(-1)) {
			status = null;
		}
    	
    	List<CrawlTaskEntity> list = null;
    	Result result = null;
		try {
			list = crawlTaskService.list(url, parentUrl, containStr, rootUrlId, status, sortType, pageIndex, pageSize);
			result = new Result(ResultConstant.SUCCESS,new PageInfo<>(list));
		} catch (Exception e) {
			logger.info(e.getMessage());
			e.printStackTrace();
			result = new Result(ResultConstant.GENERAL_ERROR.setMessage(e.getMessage()));
		}
		
	    return result;
	} 
    
    /**
	 * 请求待处理任务（同步）
	 * @param request
	 * @param clientName 客户端主机名
	 * @param clientIp 客户端IP
	 * @param clientPort 客户端端口
	 * @param requestCount 请求任务条数
	 * @return
	 * @author ServerZhang
	 * @date 2018年1月11日
	 */
    @ApiOperation("请求待处理任务（不要通过API请求此接口）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "clientName", value = "客户端主机名", paramType = "query", dataType = "string", required = false),
            @ApiImplicitParam(name = "clientIp", value = "客户端IP", paramType = "query", dataType = "string", required = false),
            @ApiImplicitParam(name = "clientPort", value = "客户端端口", paramType = "query", dataType = "Integer", required = false),
            @ApiImplicitParam(name = "requestCount", value = "请求任务条数", paramType = "query", dataType = "Integer", required = false)
    })
	@RequestMapping(value="/listUncrawled",method=RequestMethod.POST)
	public synchronized  ResultMessage listUncrawled(HttpServletRequest request,
			String clientName, String clientIp, Integer clientPort, Integer requestCount){
		
		if (StringUtil.isEmpty(clientIp)) {
			clientIp = "未知IP";
		}
		if (StringUtil.isEmpty(clientName)) {
			clientName = "未知主机名";
		}
		if (StringUtil.isEmpty(requestCount)) {
			requestCount = config.getTaskRequestCount();
		}
		
		ResultMessage result = new ResultMessage();
		List<CrawlTaskEntity> uncrawled = null;
		String message = null;
		try {
			uncrawled = crawlTaskService.listUncrawled(clientName, clientIp, clientPort, requestCount);
			result.setCode(Constant.SUCCESS_CODE);
			message="请求待处理任务成功";
		} catch (Exception e) {
			e.printStackTrace();
			logger.info(Constant.ERROR_CODE);
			result.setCode(Constant.ERROR_CODE);
			message=e.getMessage();
		}
		
		result.setMessage(message);
		result.setData(uncrawled);
		
		logger.info("code:"+result.getCode());
		logger.info("message:"+result.getMessage());
		logger.info("data:"+result.getData());
		
	    return result;
	}
    /**
     * 添加任务
     * @param request
     * @param taskJson
     * @author ServerZhang
     * @date 2018年1月12日
     */
    @ApiOperation("添加任务（不要通过API请求此接口）")
    @ApiImplicitParams({
    	@ApiImplicitParam(name = "taskJson", value = "待添加任务列表json", paramType = "query", dataType = "string", required = true)
    })
    @RequestMapping(value="/insertTask",method=RequestMethod.POST)
    public void insertTask(HttpServletRequest request,
    		String taskJson){
    	
    	if (StringUtil.isEmpty(taskJson)) {
    		return;
    	}
    	//检查字符串是否合法
    	Boolean canDo = taskJson.startsWith("[") && taskJson.endsWith("]");
    	if (!canDo) {
    		return;
		}
    	
    	crawlTaskService.insertTask(taskJson);
    }
    /**
     * 上传爬取的子页面
     * @param request
     * @param taskJson
     * @author ServerZhang
     * @date 2018年1月18日
     */
    @ApiOperation("上传爬取的子页面（不要通过API请求此接口）")
    @ApiImplicitParams({
    	@ApiImplicitParam(name = "taskJson", value = "待添加任务列表json（包含页面内容）", paramType = "query", dataType = "string", required = true)
    })
    @RequestMapping(value="/uploadSubpage",method=RequestMethod.POST)
    public void uploadSubpage(HttpServletRequest request,
    		String taskJson){
    	
    	if (StringUtil.isEmpty(taskJson)) {
    		return;
    	}
    	//检查字符串是否合法
    	Boolean canDo = taskJson.startsWith("[") && taskJson.endsWith("]");
    	if (!canDo) {
    		return;
    	}
    	
    	crawlTaskService.insertTask(taskJson);
    	//crawlTaskService.uploadSubpage(taskJson);
    }
    /**
	 * 上传文件
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="/uploadSubpageFile",method=RequestMethod.POST)
	public String uploadSubpageFile(HttpServletRequest request) {
		String uuid = StringUtil.getUUID();
		//将json以文件的形式保存在暂存目录
		if (StringUtil.isEmpty(htmlTempPath)) {
			htmlTempPath = "./temp/";
		}
		File pFile = new File(htmlTempPath);
		if (!pFile.exists()) {
			pFile.mkdirs();
		}
		
		String path = StringUtil.connectAsFilePath(htmlTempPath,uuid+".json");
		//File jsonFile = new File(path);
		
		String message=null;
		try{
			ServletInputStream sis = request.getInputStream();
			
			RandomAccessFile file=new RandomAccessFile(path,"rw");
			
			byte[] buf=new byte[1024];
			int len = sis.read(buf,0,1024);
			while(len!=-1){
				file.write(buf,0,len);
				len=sis.read(buf,0,1024);
			}
			file.close();
			sis.close();
			message="上传成功";
		}catch(Exception e){
			logger.info("上传异常");
			message="上传异常";
			e.printStackTrace();
		}
		
	    return message;
	}
    /**
     * 结束爬取，回写结果
     * @param request
     * @param taskJson
     * @author ServerZhang
     * @date 2018年1月12日
     */
    @ApiOperation("结束爬取，回写结果（不要通过API请求此接口）")
    @ApiImplicitParams({
    	@ApiImplicitParam(name = "taskJson", value = "待修改任务列表json", paramType = "query", dataType = "string", required = true)
    })
    @RequestMapping(value="/updateTask",method=RequestMethod.POST)
    public void updateTask(HttpServletRequest request,
    		String taskJson){
    	
    	if (StringUtil.isEmpty(taskJson)) {
    		return;
    	}
    	//检查字符串是否合法
    	Boolean canDo = taskJson.startsWith("[") && taskJson.endsWith("]");
    	if (!canDo) {
    		return;
    	}
    	
    	crawlTaskService.updateTask(taskJson);
    }
    /**
     * 结束爬取，回写结果
     * @param request
     * @param taskJson
     * @author ServerZhang
     * @date 2018年1月12日
     */
    @ApiOperation("结束爬取，回写结果（不要通过API请求此接口）")
    @ApiImplicitParams({
    	@ApiImplicitParam(name = "updateTaskFile", value = "待修改任务列表json", paramType = "query", dataType = "string", required = true)
    })
    @RequestMapping(value="/updateTaskFile",method=RequestMethod.POST)
    public void updateTaskFile(HttpServletRequest request,
    		String taskJson){
    	String uuid = StringUtil.getUUID();
		//将json以文件的形式保存在暂存目录
		if (StringUtil.isEmpty(htmlTempPath)) {
			htmlTempPath = "./temp/";
		}
		File pFile = new File(htmlTempPath);
		if (!pFile.exists()) {
			pFile.mkdirs();
		}
		
		String path = StringUtil.connectAsFilePath(htmlTempPath,uuid+".json");
		//File jsonFile = new File(path);
		
		String message=null;
		try{
			ServletInputStream sis = request.getInputStream();
			
			RandomAccessFile file=new RandomAccessFile(path,"rw");
			
			byte[] buf=new byte[1024];
			int len = sis.read(buf,0,1024);
			while(len!=-1){
				file.write(buf,0,len);
				len=sis.read(buf,0,1024);
			}
			file.close();
			sis.close();
			message="上传成功";
		}catch(Exception e){
			logger.info("上传异常");
			message="上传异常";
			e.printStackTrace();
		}
		
    }
    
    
}
